import axios from 'axios';
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
import { Message } from '@arco-design/web-vue';
import { getToken, clearToken } from '@/utils/auth';
import { getUTCStr } from '@/utils/timezone';
import defaultSettings from '@/config/sys-settings';
import { SM4Encrypt } from '@/utils/encryption/sm4';
import { useRouter, LocationQueryRaw, useRoute } from 'vue-router';
import { slashToDot } from '@/utils/index';
import { removeRouteListener } from '@/utils/route-listener';
import { getSign } from './request-sign';
import { verifyRequest, verifyResponse, verifyUrl } from './verify-api';

const router = useRouter();
const route = useRoute();

export interface HttpResponse<T = unknown> {
  status: number;
  msg: string;
  message?: string;
  code: number;
  data: T;
}

export interface IFusionBiz {
  timeZone?: string;
  timeFormat?: string;
  portalId?: string;
  buttonId?: string;
  apiCrypto?: any;
}

if (import.meta.env.VITE_API_BASE_URL) {
  axios.defaults.baseURL = import.meta.env.VITE_API_BASE_URL;
  axios.defaults.withCredentials = true;
  axios.defaults.timeout = 10000;
}

// 是否解密响应
const responseEncryptMap = new Map();

// 生成FusionBiz头部
export const setFusionBiz = () => {
  const FusionBiz: IFusionBiz = {};
  // 通过请求头传递时区
  const UTC = getUTCStr(defaultSettings.timezone);
  FusionBiz.timeZone = UTC;
  FusionBiz.timeFormat = 'yyyy-MM-dd HH:mm:ss';
  return SM4Encrypt(JSON.stringify(FusionBiz));
};

axios.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    let FusionBiz: IFusionBiz = {};
    // 通过请求头传递时区
    const UTC = getUTCStr(defaultSettings.timezone);
    FusionBiz.timeZone = UTC;
    FusionBiz.timeFormat = 'yyyy-MM-dd HH:mm:ss';

    const url = config.url || '';
    const len = url.indexOf('?');
    const subUrl =
      (len > -1
        ? url.substring(url.indexOf('/', 1), len)
        : url.substring(url.indexOf('/', 1))) || url;
    const requestEncrypt =
      verifyRequest(config) && defaultSettings.requestEncrypt;
    const responseEncrypt =
      verifyResponse(config) && defaultSettings.responseEncrypt;
    const apiCrypto = {
      requestEncrypt: {
        encrypt: requestEncrypt,
        ignoreUrl: requestEncrypt ? '' : subUrl,
      },
      responseEncrypt: {
        encrypt: responseEncrypt,
        ignoreUrl: responseEncrypt ? '' : subUrl,
      },
    };
    FusionBiz = { ...FusionBiz, apiCrypto };
    responseEncryptMap.set(config.url, apiCrypto.responseEncrypt.encrypt);
    config.headers = config.headers || {};
    config.headers['Fusion-Biz'] = SM4Encrypt(JSON.stringify(FusionBiz));
    if (verifyUrl(config, 'sign')) {
      config.params = getSign(config.params);
    } else {
      config.headers['Fusion-Auth'] = getToken() || '';
    }
    if (
      apiCrypto.requestEncrypt.encrypt &&
      !apiCrypto.requestEncrypt.ignoreUrl
    ) {
      // config = encrypt(config);
    }
    return config;
  },
  (error) => {
    // do something
    return Promise.reject(error);
  }
);
// add response interceptors
axios.interceptors.response.use(
  (response: AxiosResponse<HttpResponse>) => {
    if (responseEncryptMap.get(response.config.url)) {
      // response = decrypt(response);
    }
    if (response.config.responseType === 'blob') {
      return response;
    }
    const res = response.data;

    if (verifyUrl(response.config, 'cMsg')) {
      return res;
    }

    if (res.code !== 8000000) {
      if (res.message) {
        Message.warning({
          content: res.message || 'Request Error',
          duration: 3 * 1000,
        });
      }
      return Promise.reject(response);
    }

    // 将数据中HH:mm这类UTC-8时区转为当前时区
    // if (res.data && getUTCStr(store.getters[types.TIMEZONE]) !== 'UTC+08:00') {
    //   res.data = JSON.parse(matchUTCToTime(JSON.stringify(res.data)))
    // }

    return res;
  },
  (error) => {
    let message = '';
    const errMsg = error.message;
    // eslint-disable-next-line no-console
    console.log('error', error);
    if (errMsg) {
      switch (errMsg.status) {
        case 400:
          message = '错误请求';
          break;
        case 401:
          message = '未授权';
          // 跳回登录页，此时store未挂载，不能使用store，只能清除一下storage
          clearToken();
          localStorage.removeItem('username');
          removeRouteListener();
          router.push({
            name: 'login',
            query: {
              redirect: slashToDot(route.fullPath),
              ...route.query,
            } as LocationQueryRaw,
          });
          break;
        case 403:
          message = '拒绝访问';
          break;
        case 404:
          message = '请求错误,未找到该资源';
          break;
        case 405:
          message = '请求方法未允许';
          break;
        case 408:
          message = '请求超时';
          break;
        case 500:
          message = '服务器端出错';
          break;
        case 501:
          message = '网络未实现';
          break;
        case 502:
          message = '网络错误';
          break;
        case 503:
          message = '服务不可用';
          break;
        case 504:
          message = '网络超时';
          break;
        case 505:
          message = 'http版本不支持该请求';
          break;
        default:
          message = `连接错误${errMsg.status}`;
      }
      if (errMsg.config && verifyUrl(errMsg.config, 'cMsg')) {
        message = '';
      }
    }
    if (message) {
      Message.error({
        content: message || 'Request Error',
        duration: 3 * 1000,
      });
    }
    return Promise.reject(error);
  }
);
